package com.zs.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zs.blog.constant.enums.RedisConstant;
import com.zs.blog.constant.enums.ResponseResultEnum;
import com.zs.blog.converter.UserConverter;
import com.zs.blog.dao.IRoleMapper;
import com.zs.blog.dao.IUserMapper;
import com.zs.blog.exception.BusinessException;
import com.zs.blog.model.dto.UserListDTO;
import com.zs.blog.model.dto.UserLoginDTO;
import com.zs.blog.model.dto.UserSearchDTO;
import com.zs.blog.model.dto.UserUpdateTypeDTO;
import com.zs.blog.model.entity.Category;
import com.zs.blog.model.entity.User;
import com.zs.blog.model.vo.PageInfoVO;
import com.zs.blog.model.vo.UserDetailVO;
import com.zs.blog.model.vo.UserListVO;
import com.zs.blog.model.vo.UserRoleVO;
import com.zs.blog.service.IUserService;
import com.zs.blog.util.JwtUtil;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.StreamOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;

/**
 * @Title: IUserServiceImpl
 * @Author zs
 * @Package com.zs.blog.service.impl
 * @Date 2025/4/14 23:31
 * @description: 用户服务实现
 */
@Service
public class IUserServiceImpl extends ServiceImpl<IUserMapper, User> implements IUserService {

    public IUserMapper userMapper;
    public IRoleMapper roleMapper;
    private final StringRedisTemplate stringRedisTemplate;

    public IUserServiceImpl(IUserMapper userMapper, IRoleMapper roleMapper, StringRedisTemplate stringRedisTemplate) {
        this.userMapper = userMapper;
        this.roleMapper = roleMapper;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 用户登录
     *
     * @param username 用户名
     * @param password 密码
     */
    @Override
    public UserLoginDTO login(String username, String password) {

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getUsername, username);
        User user = userMapper.selectOne(lqw);

        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 生成Token
        UserLoginDTO userToken = JwtUtil.getToken(user);

        // 将Token存入redis中
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        ops.set(RedisConstant.ACCESS_TOKEN, userToken.getAccessToken());
        ops.set(RedisConstant.REFRESH_TOKEN, userToken.getRefreshToken());

        return userToken;
    }

    /**
     * 用户注册
     *
     * @param user 用户实体类
     */
    @Override
    public void register(User user) {
        System.out.println(user);
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getUsername, user.getUsername());
        User userInfo = userMapper.selectOne(lqw);

        if (userInfo == null) {
//            userMapper.insert(userInfo);
        }
    }

    /**
     * 获取分页的用户信息列表
     *
     * @param pageNum  页码
     * @param pageSize 数据数
     * @return
     */
    @Override
    public PageInfoVO<UserListVO> listUserWithPagination(Integer pageNum, Integer pageSize) {

        Page<User> page = new Page<>(pageNum, pageSize);
        List<User> userList = userMapper.selectList(page, null);

        // 数据映射
        return packUserListVOByPageInfoVO(page, userList);
    }

    /**
     * 根据用户ID获取用户详情信息
     *
     * @param userId 用户ID
     * @return 用户详情
     */
    @Override
    public UserDetailVO getUserDetailByUserId(Long userId) {
        // 获取用户信息
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getId, userId);
        User user = userMapper.selectOne(lqw);

        if (user != null) {
            // 数据映射并返回
            UserDetailVO userDetail = UserConverter.INSTANCE.user2UserDetailVO(user);
            // 获取用户角色列表信息并设置
            userDetail.setUserRoleList(roleMapper.listRoleByUserId(userDetail.getId()));
            return userDetail;
        }

        return null;

    }

    /**
     * 更新用户状态
     *
     * @param userUpdateTypeDTO 更新用户状态数据转换对象
     */
    @Override
    public void updateUserType(UserUpdateTypeDTO userUpdateTypeDTO) {
        LambdaUpdateWrapper<User> luw = new LambdaUpdateWrapper<>();
        luw.eq(User::getId, userUpdateTypeDTO.getId()).set(User::getIsDisabled, userUpdateTypeDTO.getIsDisabled());
        userMapper.update(luw);
    }

    /**
     * 通过搜索条件获取分页的分类列表
     *
     * @param userSearchDTO 用户搜索条件
     * @return
     */
    @Override
    public PageInfoVO<UserListVO> listUserBySearchCondition(UserSearchDTO userSearchDTO) {
        Page<User> page = new Page<>(userSearchDTO.pageNum, userSearchDTO.pageSize);

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StringUtils.isNotBlank(userSearchDTO.getUsername()), User::getUsername, userSearchDTO.username);
        lqw.eq(StringUtils.isNotBlank(userSearchDTO.getEmail()), User::getEmail, userSearchDTO.getEmail());
        lqw.eq(userSearchDTO.getIsDisabled() != null, User::getIsDisabled, userSearchDTO.getIsDisabled());
        if (userSearchDTO.getStartTime() != null && userSearchDTO.getEndTime() != null) {
            lqw.between(User::getCreateTime, userSearchDTO.getStartTime(), userSearchDTO.getEndTime());
        }
        List<User> userList = userMapper.selectList(page, lqw);

        return packUserListVOByPageInfoVO(page, userList);
    }

    /**
     * 根据用户ID删除用户信息
     *
     * @param userIdList 用户ID列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUserByIds(List<Long> userIdList) {
        // 受影响的行数
        int affectedRows = userMapper.updateUserByIds(userIdList);
        // 失败的行数
        int failureRows = affectedRows - userIdList.toArray().length;
        // 失败就抛出自定义异常
        if (failureRows < 0) {
            throw new BusinessException("有" + Math.abs(failureRows) + "行更新失败");
        }
    }


    @NotNull
    private PageInfoVO<UserListVO> packUserListVOByPageInfoVO(Page<User> page, List<User> userList) {
        List<UserListVO> userListVO = UserConverter.INSTANCE.userList2UserListVO(userList);

        userListVO.forEach(item -> {
            List<UserRoleVO> userRoleList = roleMapper.listRoleByUserId(item.getId());
            item.setUserRoleList(userRoleList);
        });

        PageInfoVO<UserListVO> pageInfo = new PageInfoVO<>();
        pageInfo.setTotal(page.getTotal());
        pageInfo.setItems(userListVO);

        return pageInfo;
    }


}
